module Datapath (Clock, RegDest, ALUSrc, RegWrite, MemWrite, ALUControl, MemToReg, Branch, Result);

	input 			Clock, RegDest, ALUSrc, RegWrite, MemWrite, MemToReg, Branch;
	input [2:0] 	ALUControl;
	output [31:0]		Result;
	
	wire [31:0] Instr, RegOutA, RegOutB, ALUInA, ALUInB, SignImm,
		PCPlus4, PCB, PCBranch, WriteData, ALUResult, ReadData, Result;
	wire [4:0]	WriteReg;
	wire			Zero;
	wire 			Jump;
	
	reg [31:0]	PC;
	
	assign PCPlus4 = PC + 4;
	assign PCSrc = Branch && Zero;
	assign PCB = PCSrc ? PCBranch : PCPlus4;
	assign ALUInA = RegOutA;
	assign ALUInB = ALUSrc ? SignImm : RegOutB;
	assign SignImm = {{16{Instr[15]}}, Instr[15:0]};
	assign PCBranch = PCPlus4 + (SignImm << 2);
	assign WriteReg = RegDest ? Instr[15:11] : Instr[20:16];
	assign WriteData = RegOutB;
	assign Result = MemToReg ? ReadData : ALUResult;
	
	always @(posedge Clock) begin
		PC <= PCB;
	end
	
	Memory memory(.Clock(Clock),
		.A1(ALUResult), .A2(PC),
		.RD1(ReadData), .RD2(Instr),
		.WD1(WriteData), .WE(MemWrite));
	
	RegisterFile regfile(.Clock(Clock),
		.A1(Instr[25:21]), .A2(Instr[20:16]),
		.RD1(RegOutA), .RD2(RegOutB),
		
		.A3(WriteReg), .WE3(RegWrite), .WD3(Result));
	
	ALU alu(.A(ALUInA), .B(ALUInB), .Control(ALUControl), .Result(ALUResult), .Zero(Zero));

	
endmodule
